package businessEntities;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Holds data about set of columns from specific table.
 * Currently : Database name, table name, column's specific MySQL type, column is null-able/not null-able, data type of the column.
 */
public class ColumnsInformationContainer {

    private final List<String> columns;
    private final Map<String, List<String>> columnsData;
    private final String databaseName;
    private final String tableName;

    /**
     * Creates new empty container.
     * @param databaseName
     * @param tableName 
     */
    public ColumnsInformationContainer(String databaseName, String tableName) {
        this.databaseName = databaseName;
        this.tableName = tableName;
        columns = new ArrayList<>();
        columnsData = new HashMap<>();
    }

    /**
     * Adds column to the container.
     * @param columnName
     * @param columnType
     * @param isNullable -  only "YES" or "NO" are valid.
     * @param dataType
     * @throws IllegalArgumentException <nl/>1. <code>isNullable</code> is differ from "YES" or "NO.
     *                                  <nl/>2. The container already contains <code>columnType</code>.
     * @throws NullPointerException if <code>columnName == null || columnType == null || isNullable == null || dataType == null</code>
     */
    public void addColumn(String columnName, String columnType, String isNullable, String dataType) {
        if (columnName == null || columnType == null || isNullable == null || dataType == null) {
            throw new NullPointerException("One or more null parameters");
        }
        if (!isNullable.equals("NO") && !isNullable.equals("YES")) {
            throw new IllegalArgumentException("Column null-ability can be only 'YES' OR 'NO': " + isNullable);
        }
        if (columnsData.containsKey(columnName)) {
            throw new IllegalArgumentException("The container allready contains the column: " + columnName);
        }

        columns.add(columnName);
        columnsData.put(columnName, Arrays.asList(columnType, isNullable, dataType));
    }

    public List<String> getColumsCopy() {
        return new ArrayList<>(columns);
    }

    /**
     * Return the column's MySQL type.
     * @param columnName - String. Column name to check for. 
     * @return <code>columnName</code> MySQL type.
     * @throws IllegalArgumentException if the column was not found in the container.
     */
    public String getColumnType(String columnName) {
        if (!columnsData.containsKey(columnName)) {
            throw new IllegalArgumentException("Column was not found: " + columnName);
        }
        return (columnsData.get(columnName)).get(0);
    }

    /**
     * Check if a column is null able or not.
     * @param columnName - String. Column name to check for.
     * @return true if and only if <code>columnName</code> is null able.
     * @throws IllegalArgumentException if the column was not found in the container.
     */
    public boolean isNullableColumn(String columnName) {
        if (!columnsData.containsKey(columnName)) {
            throw new IllegalArgumentException("Column was not found: " + columnName);
        }
        String isNullable = (columnsData.get(columnName)).get(1);
        if (isNullable.equals("YES")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Returns the column's data type.
     * @param columnName - String. Column name to check for.
     * @return true if and only if <code>columnName</code> is null able.
     * @throws IllegalArgumentException if the column was not found in the container.
     */
    public String getDataType(String columnName) {
        if (!columnsData.containsKey(columnName)) {
            throw new IllegalArgumentException("Column was not found: " + columnName);
        }
        String dataType = (columnsData.get(columnName)).get(2);
        return dataType;
    }

    public String[] getOperators(String columnName) {
        if (!columnsData.containsKey(columnName)) {
            throw new IllegalArgumentException("Column was not found: " + columnName);
        }
        if (isNullableColumn(columnName)) {
            return new String[]{"=", "!=", "<", "<=", ">", ">=", "LIKE", "NOT LIKE", "IS NULL", "IS NOT NULL"};
        } else {
            return new String[]{"=", "!=", "<", "<=", ">", ">=", "LIKE", "NOT LIKE"};
        }
    }

    public String getDatabaseName() {
        return databaseName;
    }

    public String getTableName() {
        return tableName;
    }
}
